<?php


namespace App\Logic;

use App\Common\lib\Code;
use App\Exception\ApiException;
use App\Models\NumberModel;
use App\Models\SchoolModel;
use App\Models\ToolsModel;
use Endroid\QrCode\QrCode;
use http\Client;
use itbdw\Ip\IpLocation;
use EasySwoole\EasySwoole\Config as GlobalConfig;
use Overtrue\Pinyin\Pinyin;

class ToolsLogic
{
    //ip查询
    public function ip($ip = ''): array
    {
        $data = ['ip' => $ip];
        $defaultErrorMsg = ['isIp' => ':fieldName不是有效的IP地址',];
        $validate = new \EasySwoole\Validate\Validate();
        $validate->addColumn('ip')->required()->isIp();
        $bool = $validate->validate($data); // 验证结果：验证通过返回true 反之返回false
        if (!$bool) {
            throw new ApiException($validate->getError()->__toString());
        }
        $qqwry_filepath = EASYSWOOLE_ROOT . '/static/qqwry.dat';
        return IpLocation::getLocation(trim($ip), $qqwry_filepath);
    }

    /**
     * 在线翻译
     * @param $q
     * @param $form
     * @param $to
     * @throws ApiException
     */
    public function fanyi($q, $form, $to)
    {
        $baidu = GlobalConfig::getInstance()->getConf("BAIDU");
        //zh 中文 yue 粤语 kor 韩语 th 泰语 th 泰语 pt 葡萄牙语 cht 繁体中文 en 英语 jp 日语 ru 俄语 spa 西班牙语  it 意大利语
        if (empty($q)) throw new ApiException("文本不能为空");
        if (empty($form)) throw new ApiException("翻译源语言请选择");
        if (empty($to)) throw new ApiException("翻译目标语言请选择");
        $args = array(
            'q' => str_replace(PHP_EOL, '', $q),
            'appid' => $baidu['BAIDU_APPID'],
            'salt' => rand(10000, 99999),
            'from' => $form,
            'to' => $to,
        );
        $args['sign'] = self::buildSign($args['q'], $baidu['BAIDU_APPID'], $args['salt'], $baidu['BAIDU_KEY']);
        $ret = self::call($baidu['BAIDU_URL'], $args);
        return json_decode($ret, true);
    }

    /**
     * 汉字转拼音
     * @param array $params
     * @throws ApiException
     */
    public function pinyin($text = ''): array
    {
        if (empty($text)) throw new ApiException("请输入文本");
        if (mb_strlen($text) > 600) throw new ApiException("最多600个字符");
        $pinyin = new Pinyin();
        return $pinyin->convert($text);
    }

    /**
     * RMB大写转换
     * @param string $text
     * @return string
     * @throws ApiException
     */
    public function rmb($text = '')
    {
        if (empty($text) || !is_numeric($text)) throw new ApiException('请输入数字');
        $text = self::rmbTo($text);
        return $text;
    }

    /**
     * 新华字典
     * @param string $text
     */
    public function dictionary($text = '')
    {
        $ali = GlobalConfig::getInstance()->getConf("ALI");
        if (empty($text)) throw new ApiException("请输入汉字!");
        if (!preg_match("/[\x7f-\xff]/", $text)) {
            throw new ApiException("请输入汉字!");
        }
        $host = $ali['API_ADD'] . trim($text);
        $headers = ["Authorization" => "APPCODE " . $ali['AppCode']];
        $client = new \GuzzleHttp\Client();
        $rs = $client->request('GET', $host, ['headers' => $headers]);
        $body = json_decode($rs->getBody(), true);
        return $body['result'];
    }

    /**
     * 高校查询
     * @param array $params
     * @return array
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     */
    public function school($params = [])
    {
        $page = !empty($params['page']) ? $params['page'] : 1;
        $limit = !empty($params['limit']) ? $params['limit'] : 10;
        $model = SchoolModel::create()->limit($limit * ($page - 1), $limit)->withTotalCount();;
        if (!empty($params['name'])) {
            $model->where('school', '%' . $params['name'] . '%', 'like');
        }
        $list = $model->all();
        $result = $model->lastQueryResult();
        $total = $result->getTotalCount();
        return ['page' => $page, 'limit' => $limit, 'list' => $list, 'total' => $total];
    }

    /**
     * 二维码生成
     * @param array $params
     * @throws ApiException
     */
    public function qrcode($params = [])
    {
        if (empty($params['text'])) {
            throw new ApiException("请输入内容");
        }
        $qrCode = new QrCode($params['text']);
        // 内容区域宽高,默认为300
        $qrCode->setSize(300);
        // 外边距大小,默认为10
        $qrCode->setMargin(10);
        // 设置编码
        $qrCode->setEncoding('UTF-8');
        return $qrCode->writeDataUri();
    }

    /**
     * 号码归属地查询
     * @param array $params
     */
    public function phoneArea($params = [])
    {
        if (empty($params['phone'])) {
            throw new ApiException("手机号码不能为空");
        }
        $phone = NumberModel::create()->get(['number' => trim($params['phone'])]);;
        if (!empty($phone)) {
            return $phone;
        }
        $client = new \GuzzleHttp\Client();
        $conf = GlobalConfig::getInstance()->getConf("ALI");
        $rs = $client->request('GET', $conf['QUERY_PHONE'] . $params['phone']);
        $body = json_decode($rs->getBody(), true);
        if (empty($body['data'])) {
            throw new ApiException("号码错误");
        }
        NumberModel::create([
            'number' => $params['phone'],
            'province' => $body['data']['province'],
            'city' => $body['data']['city'],
            'sp' => !empty($body['data']['sp']) ? $body['data']['sp'] : "暂无",
        ])->save();
        $body['data']['number'] = $params['phone'];
        return $body['data'];
    }

    /**
     * RMB大写转换方法
     * @param $num
     * @return string
     */
    public static function rmbTo($num): string
    {
        $c1 = "零壹贰叁肆伍陆柒捌玖";
        $c2 = "分角元拾佰仟万拾佰仟亿";
        //精确到分后面就不要了，所以只留两个小数位
        $num = round($num, 2);
        //将数字转化为整数
        $num = $num * 100;
        if (strlen($num) > 10) {
            throw new ApiException("金额太大，请检查");
        }
        $i = 0;
        $c = "";
        while (1) {
            if ($i == 0) {
                //获取最后一位数字
                $n = substr($num, strlen($num) - 1, 1);
            } else {
                $n = $num % 10;
            }
            //每次将最后一位数字转化为中文
            $p1 = substr($c1, 3 * $n, 3);
            $p2 = substr($c2, 3 * $i, 3);
            if ($n != '0' || ($n == '0' && ($p2 == '亿' || $p2 == '万' || $p2 == '元'))) {
                $c = $p1 . $p2 . $c;
            } else {
                $c = $p1 . $c;
            }
            $i = $i + 1;
            //去掉数字最后一位了
            $num = $num / 10;
            $num = (int)$num;
            //结束循环
            if ($num == 0) {
                break;
            }
        }
        $j = 0;
        $slen = strlen($c);
        while ($j < $slen) {
            //utf8一个汉字相当3个字符
            $m = substr($c, $j, 6);
            //处理数字中很多0的情况,每次循环去掉一个汉字“零”
            if ($m == '零元' || $m == '零万' || $m == '零亿' || $m == '零零') {
                $left = substr($c, 0, $j);
                $right = substr($c, $j + 3);
                $c = $left . $right;
                $j = $j - 3;
                $slen = $slen - 3;
            }
            $j = $j + 3;
        }
        //这个是为了去掉类似23.0中最后一个“零”字
        if (substr($c, strlen($c) - 3, 3) == '零') {
            $c = substr($c, 0, strlen($c) - 3);
        }
        //将处理的汉字加上“整”
        if (empty($c)) {
            return "零元整";
        } else {
            return $c . "整";
        }
    }

    /**
     * 加密
     * @param $query
     * @param $appID
     * @param $salt
     * @param $secKey
     * @return string
     */
    public static function buildSign($query, $appID, $salt, $secKey)
    {
        $str = $appID . $query . $salt . $secKey;
        $ret = md5($str);
        return $ret;
    }

    //发起请求
    public static function call($url, $args = null, $method = "post", $testflag = 0, $timeout = 10, $headers = array())
    {/*{{{*/
        $ret = false;
        $i = 0;
        while ($ret === false) {
            if ($i > 1)
                break;
            if ($i > 0) {
                sleep(1);
            }
            $ret = self::callOnce($url, $args, $method, false, $timeout, $headers);
            $i++;
        }
        return $ret;
    }

    //请求
    public static function callOnce($url, $args = null, $method = "post", $withCookie = false, $timeout = 10, $headers = array())
    {
        $ch = curl_init();
        if ($method == "post") {
            $data = self::convert($args);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_POST, 1);
        } else {
            $data = convert($args);
            if ($data) {
                if (stripos($url, "?") > 0) {
                    $url .= "&$data";
                } else {
                    $url .= "?$data";
                }
            }
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        if (!empty($headers)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        }
        if ($withCookie) {
            curl_setopt($ch, CURLOPT_COOKIEJAR, $_COOKIE);
        }
        $r = curl_exec($ch);
        curl_close($ch);
        return $r;
    }

    //签名
    public static function convert(&$args)
    {
        $data = '';
        if (is_array($args)) {
            foreach ($args as $key => $val) {
                if (is_array($val)) {
                    foreach ($val as $k => $v) {
                        $data .= $key . '[' . $k . ']=' . rawurlencode($v) . '&';
                    }
                } else {
                    $data .= "$key=" . rawurlencode($val) . "&";
                }
            }
            return trim($data, "&");
        }
        return $args;
    }

    /**
     * 工具详情
     * @param int $tools_id
     * @return ToolsModel|array|bool|\EasySwoole\ORM\AbstractModel|\EasySwoole\ORM\Db\Cursor|\EasySwoole\ORM\Db\CursorInterface|null
     * @throws \EasySwoole\Mysqli\Exception\Exception
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     */
    public function detail($tools_id = 0)
    {
        return ToolsModel::create()->get(['tools_id' => $tools_id]);

    }

    /**
     * 工具列表
     * @param array $params
     * @return array|bool|\EasySwoole\ORM\Collection\Collection|\EasySwoole\ORM\Db\Cursor|\EasySwoole\ORM\Db\CursorInterface
     * @throws \EasySwoole\ORM\Exception\Exception
     * @throws \Throwable
     */
    public function lists($params = [])
    {
        return ToolsModel::create()->where('is_open', 0)->order('sort', 'desc')->all();

//        //redis缓存
//        $redis = new \EasySwoole\Redis\Redis(new \EasySwoole\Redis\Config\RedisConfig(GlobalConfig::getInstance()->getConf('REDIS')));
//        $lists = $redis->get('lists');
//        if (empty($lists)) {
//            $all = ToolsModel::create()->where('is_open', 0)->order('sort', 'desc')->all();
//            $redis->set('lists', json_encode($all));
//            return $all;
//        } else {
//            $lists = json_decode($lists, true);
//            return $lists;
//        }
    }
}